package com.xmfh.wemedia.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmfh.wemedia.dto.VideoDTO;
import com.xmfh.wemedia.exception.DatabaseInsertionError;
import com.xmfh.wemedia.exception.FileCopyException;
import com.xmfh.wemedia.exception.FileNoNameException;
import com.xmfh.wemedia.mapper.DdVideoMapper;
import com.xmfh.wemedia.model.DdVideo;
import com.xmfh.wemedia.service.IDdVideoService;
import com.xmfh.wemedia.util.FileDirectory;
import com.xmfh.wemedia.util.JsonResult;
import com.xmfh.wemedia.vo.VideoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author admin
 * @since 2022-04-06
 */
@Slf4j
@Service
public class DdVideoServiceImpl extends ServiceImpl<DdVideoMapper, DdVideo> implements IDdVideoService {

    private String originalFileName;

    @Autowired
    private DdVideoMapper mapper;

    @Autowired
    private FileDirectory directory;

    @Override
    public JsonResult<List<DdVideo>> getHotVideo() {
        return JsonResult.ok(mapper.getVideoByHot());
    }

    @Override
    public String uploadFile(File localStorage, File localTargetStorage, MultipartFile file) throws RuntimeException {
        originalFileName = file.getOriginalFilename();
        if (originalFileName == null)
            throw new FileNoNameException("视频未命名");
        try {
            File localFile = new File(localStorage, originalFileName);
            file.transferTo(localFile);
            Files.copy(localFile.toPath(), new File(localTargetStorage, originalFileName).toPath());
        } catch (IOException e) {
            e.printStackTrace();
            throw new FileCopyException("上传视频出错");
        }
        return originalFileName;
    }

    @Override
    public void deleteUploadedFile(File localStorage, File localTargetStorage, String name) {
        new File(localStorage, name).delete();
        new File(localTargetStorage, name).delete();
    }

    @Override
    public VideoDTO uploadVideoInfo(VideoVo video) throws RuntimeException {
        log.info("Video Object = \n{}", video);
        DdVideo ddVideo = new DdVideo();
        /*用户未上传视频的错误提示*/
        if (video.getOriginalVideoName() == null)
            throw new FileNoNameException("请选择上传文件");
        /*当用户未输入视频标题时，将使用原视频名作为标题*/
        ddVideo.setTitle(video.getTitle());
        if (video.getTitle() == null) {
            ddVideo.setTitle(video.getOriginalVideoName());
        }
        /*当用户未上传视频封面时，将使用默认视频封面*/
        String originalCoverName = video.getOriginalCoverName();
        String originalVideoName = video.getOriginalVideoName();
        if (originalCoverName == null) {
            ddVideo.setImgUrl("/img/default_cover.jpg");
        } else {
            String uniqueCoverName = urlGenerator(directory.getLocalCoverStorage(), originalCoverName);
            ddVideo.setImgUrl("/img/" + uniqueCoverName);
            renameLocalTargetFile(directory.getLocalTargetCoverStorage(), uniqueCoverName, originalCoverName);
        }
        String uniqueVideoName = urlGenerator(directory.getLocalVideoStorage(), originalVideoName);
        ddVideo.setStyleFlag(DdVideoMapper.styleFlag.SINGLE.getFlag())
                .setDesc(video.getDesc())
                .setFabulous(0)
                .setComment(0)
                .setViews(0)
                .setHot(0)
                .setUserId(video.getUserId())
                .setCreateTime(LocalDateTime.now())
                .setVideoUrl("/video/" + uniqueVideoName);
        renameLocalTargetFile(directory.getLocalTargetVideoStorage(), uniqueVideoName, originalVideoName);
        if (mapper.insertNewVideo(ddVideo) != 1)
            throw new DatabaseInsertionError("数据库发生错误，详情请查看日志");
        ddVideo.setId(mapper.getVideoIdByVideoUrl(ddVideo.getVideoUrl()));
        return videoDTOGenerator(ddVideo);
    }

    @Override
    public List<DdVideo> getPersonalVideo(Integer id) {
        return mapper.getPersonalVideoById(id);
    }

    /**
     * 生成对应的DTO对象
     *
     * @param ddVideo 数据库内的视频文件字段
     * @return 对应的简化DTO对象
     */
    private VideoDTO videoDTOGenerator(DdVideo ddVideo) {
        VideoDTO videoDTO = new VideoDTO();
        videoDTO.setPubTime(ddVideo.getCreateTime());
        videoDTO.setUserId(ddVideo.getUserId());
        videoDTO.setResourceId(ddVideo.getId());
        return videoDTO;
    }

    /**
     * 生成文件名称，包括视频文件以及封面文件
     *
     * @param path         保存路径
     * @param originalName 原文件名
     * @return 修改后文件名称
     */
    private String urlGenerator(File path, String originalName) {
        UUID uuid = UUID.randomUUID();
        String suffix = originalName.substring(originalName.lastIndexOf('.'));
        File file = new File(path, uuid + suffix);
        new File(path, originalName).renameTo(file);
        return file.getName();
    }

    /**
     * 修改target目录下相关的文件名
     *
     * @param path         相应的文件目录
     * @param uniqueName   唯一文件名
     * @param originalName 原文件名
     */
    private void renameLocalTargetFile(File path, String uniqueName, String originalName) {
        new File(path, originalName).renameTo(new File(path, uniqueName));
    }
}
